package com.wpen.unit.core;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.DisposableBean;

import com.wpen.unit.core.service.AgentScheduleHandler;
import com.wpen.unit.utils.SpringUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 调度器调度
 * 
 * @author Wang Peng
 * @date 2022-12-11
 */
@Slf4j
public class AgentScheduleWorker extends ZyxWorker implements DisposableBean {
    private static final AgentScheduleWorker instance = new AgentScheduleWorker();

    public static AgentScheduleWorker getInstance() {
        return instance;
    }

    /* 监控间隔时间，单位毫秒 */
    private final long loopMonitor = 15000;
    private final long loopExecutor = 5000;

    private Thread agentMonitor;
    private Thread jobExecutor;
    private volatile boolean monitorRunning = true;
    private volatile boolean jobExecutorRunning = true;

    /**
     * 1、监控执行器在线状态，，请求探针检测是否在线，这个是个多线程 <br />
     * 2、调度执行作业，，这个也是个多线程
     */
    public void start() {
        log.info(this.getClass().getName() + " start...");

        agentMonitor = new Thread(new Runnable() {
            // 常驻在线子线程
            @Override
            public void run() {
                // 检测是否启动完成
                checkAppStarted();
                // 批次扫描线程
                while (monitorRunning) {
                    // 每次执行耗时，毫秒
                    long start = System.currentTimeMillis();
                    try {
                        AgentScheduleHandler scheduleHandler = SpringUtil.getBean(AgentScheduleHandler.class);
                        scheduleHandler.agentMonitor();
                    } catch (Exception e) {
                        log.error("Agent Monitor Thread Exception>" + e.getMessage(), e);
                    } finally {
                        try {
                            long cost = System.currentTimeMillis() - start;
                            TimeUnit.MILLISECONDS.sleep(loopMonitor - cost);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        agentMonitor.setDaemon(true);
        agentMonitor.setName("schedule-agent-monitor");
        agentMonitor.start();
        log.info(agentMonitor.getName() + " running...");

        jobExecutor = new Thread(new Runnable() {
            // 常驻在线子线程
            @Override
            public void run() {
                // 检测是否启动完成
                checkAppStarted();
                // 批次扫描线程
                while (jobExecutorRunning) {
                    // 每次执行耗时，毫秒
                    long start = System.currentTimeMillis();
                    try {
                        AgentScheduleHandler scheduleHandler = SpringUtil.getBean(AgentScheduleHandler.class);
                        scheduleHandler.jobExecutor();
                    } catch (Exception e) {
                        log.error("Job Executor Thread Exception>" + e.getMessage(), e);
                    } finally {
                        try {
                            long cost = System.currentTimeMillis() - start;
                            TimeUnit.MILLISECONDS.sleep(loopExecutor - cost);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        jobExecutor.setDaemon(true);
        jobExecutor.setName("schedule-job-executor");
        jobExecutor.start();
        log.info(jobExecutor.getName() + " running...");

    }

    public void destroy() {
        monitorRunning = false;
        jobExecutorRunning = false;
        log.info(this.getClass().getName() + " bye..");
    }

}
